#!/usr/bin/python3
# encoding=utf-8

import time
import json
import socket

import serial


class SerialServer(object):
    DEFAULT_TIMEOUT = 3

    def __init__(self, port, bitrate, timeout=None):
        self.port = port
        self.bitrate = bitrate
        if timeout is None:
            self.timeout = SerialServer.DEFAULT_TIMEOUT
        else:
            self.timeout = timeout
        #self.ser = serial.Serial(self.port, self.bitrate, timtout=self.timeout)
        self.ser = serial.Serial("/dev/ttyAMA0", 9600, timeout=2)
        self.ser.flushInput()

    def read(self, n):
        return self.ser.read(n)

    def write(self, s):
        return self.ser.write(s)

    # 串口转发接口
    # 首字节表示协议， 0-http
    #
    def run(self):
        def http_ok():
            msg = json.dumps({"code": 0, "msg": "ok", "time": time.time()})
            res = "HTTP / 1.1 200 OK\r\n" \
                + "Content-Length: %d\r\n" % len(msg) \
                + "\r\n" \
                + msg
            return res.encode("utf-8")

        car_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        while True:
            # 按照http协议接收，先接收\r\n\r\n
            ready_bytes =  self.ser.inWaiting()
            if ready_bytes < 1:
                continue

            start = 0
            recv_buf = self.read(ready_bytes).decode()
            print("ready_bytes", ready_bytes, recv_buf)
            end = recv_buf.find("\r\n")
            if end != -1:
                request_status = recv_buf[:end]
            else:
                while True:
                    ready_bytes =  self.ser.inWaiting()
                    if ready_bytes > 0:
                        buf = self.read(ready_bytes)
                        recv_buf += buf.decode()
                        end = recv_buf.find("\r\n")
                        if end != -1:
                            request_status = recv_buf[:end]
                            break

            start = end + len("\r\n")
            #print("startxxx", recv_buf[start:], "rr", recv_buf)

            request_headers = ""
            end = recv_buf.find("\r\n\r\n", start)
            if end != -1:
                request_headers = recv_buf[start: end]
            else:
                while True:
                    ready_bytes =  self.ser.inWaiting()
                    if ready_bytes > 0:
                        buf = self.read(ready_bytes)
                        recv_buf += buf.decode()
                        end = recv_buf.find("\r\n\r\n", start)
                        if end != -1:
                            request_headers = recv_buf[start: end]
                            break

            start = end + len("\r\n\r\n")

            content_length = 0
            target_module = None
            headers = request_headers.split("\r\n")
            for header in headers:
                pos = header.find(":")
                key = header[:pos]
                value = header[pos + 1:]
                key = key.strip().upper()
                value = value.strip()
                if key == "CONTENT-LENGTH":
                    content_length = int(value)
                elif key == "TARGET-MODULE":  # 转发目标模块，不同的模块协议不一样
                    target_module = value

            #print("already read %d byte, need read %dbyte" % (len(recv_buf[start:]), content_length - len(recv_buf[start:])))
            buf = self.read(content_length - len(recv_buf[start:]))
            recv_buf += buf.decode()
            request_body = recv_buf[start:]
            #print("#3", request_body)

            if target_module.upper() == "CAR-CONTROLLER":  # 控制小车，udp
                car_sock.sendto(request_body.encode(), ('127.0.0.1', 8848))
            #print(headers)
            #print(request_body)
            print(recv_buf)
            self.write(http_ok())
            #print('response', http_ok())


def main():
    server = SerialServer("/dev/ttyAMA0", 9600)
    server.run()


if __name__ == "__main__":
    main()
